﻿using BluetoothMachine.Attributes;
using BluetoothMachine.Models;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using BluetoothMachine.Enums;

namespace BluetoothMachine.Domains
{
    /// <summary>
    /// 服务展现
    /// </summary>
    public class ServiceDiscovery
    {
        private readonly static object _obj = new object();
        private static ServiceDiscovery _serviceDiscovery = null;
        /// <summary>
        /// 单例类数据字典：名称，类
        /// </summary>
        private static readonly ConcurrentDictionary<string, object> singletons = new ConcurrentDictionary<string, object>();
        /// <summary>
        /// 页面数据字典： 页面名称，页面对象
        /// </summary>
        private static readonly Dictionary<string, object> pages = new Dictionary<string, object>();
        public static ServiceDiscovery GetObject
        {
            get
            {
                if (_serviceDiscovery == null)
                {
                    lock (_obj)
                    {
                        if (_serviceDiscovery == null) _serviceDiscovery = new ServiceDiscovery();
                    }
                }
                return _serviceDiscovery;
            }
        }

        private ServiceDiscovery()
        {
            //获取包含当前执行的代码的程序集Assembly ass =Assembly.GetExecutingAssembly();
            //获取此程序集中定义的所有类型
            var types = Assembly.GetExecutingAssembly().GetTypes();
            var parameter = types.Where(t => t.IsClass && t.Name.Contains("ViewModel")).ToList();
            //带自定义属性的 xaml 页面
            var page = types.Where(t => t.IsClass && t.GetCustomAttribute<CustomPageAttribute>() != null).ToList();
            //单例
            var singleton = types.Where(t => t.IsClass && t.GetCustomAttribute<SingletonAttribute>() != null).ToList();
            foreach (var item in singleton)
            {
                singletons.TryAdd(item.Name, Activator.CreateInstance(item));
            }
            //取出功能页面
            for (int i = 1; i <= page.Count; i++)
            {
                Type item = page.Where(x => x.GetCustomAttribute<CustomPageAttribute>().Index == i).FirstOrDefault();                
                string title = item.GetCustomAttribute<CustomPageAttribute>().Name;//页面名称
                Type type = parameter.Where(t => t.Name == $"{item.Name}ViewModel").FirstOrDefault();//页面对应数据模型
                var ps = type.GetConstructors()[^1].GetParameters();//取最后一个索引数据 ^1从后往前数第一个下标
                List<object> plist = new List<object>();
                foreach (var p in ps)
                {
                    plist.Add(singletons.ContainsKey(p.ParameterType.Name) ? singletons[p.ParameterType.Name] : null);
                }
                object obj = Activator.CreateInstance(item);
                (obj as System.Windows.Controls.ContentControl).DataContext = Activator.CreateInstance(type, plist.ToArray());
                pages.TryAdd(title, obj);
            }
        }
        /// <summary>
        /// 单例类解析
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        public static object ResolveSingleton(Type obj) => singletons.ContainsKey(obj.Name) ? singletons[obj.Name] : null;
        /// <summary>
        /// 单例类解析
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public static T ResolveSingleton<T>() where T : new() => (T)(singletons.ContainsKey(typeof(T).Name) ? singletons[typeof(T).Name] : null);
        /// <summary>
        /// 页面解析
        /// </summary>
        /// <param name="type"></param>
        /// <returns></returns>
        public static List<LabelModel> ResolvePage(AuthorityType type)
        {
            List<LabelModel> list = new List<LabelModel>();
            foreach (var item in pages)
            {
                if (type == AuthorityType.普工)
                {
                    if (item.Key == "主 页" || item.Key == "生产配置")
                    {
                        list.Add(new LabelModel() { Content = item.Value, Title = item.Key });
                    }
                    continue;
                }
                list.Add(new LabelModel() { Content = item.Value, Title = item.Key });
            }
            return list;
        }
    }
}
